package beautiful.butterfly.drds.binlog.handlers;


import beautiful.butterfly.drds.binlog.command.FetchBinlogChecksumCommand;
import beautiful.butterfly.drds.binlog.command.FetchBinlogNamePositionCommand;
import beautiful.butterfly.drds.binlog.connection.ConnectionAttributes;
import beautiful.butterfly.drds.binlog.netty.server.NioSocketChannelExtend;
import beautiful.butterfly.drds.binlog.utils.Constants;
import beautiful.butterfly.drds.binlog.utils.Nettys;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class AuthenticateResultChannelInboundHandler extends SimpleChannelInboundHandler<ByteBuf>
{


    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception
    {
        //
        try
        {
            // 验证结果，既然能到这里，说明是正确的
            // 前面验证了肯定不是-1(0xFF),必须为0x00才是正确的
            // 不需要做任何验证
            // :)
            // 再发送一个命令,前提是自己没有设置指定的binlogname & binlogFilePosition
            {
                // 根据需要决定是否发送fetchBinlogName&Position
                ConnectionAttributes connectionAttributes = ((NioSocketChannelExtend) channelHandlerContext.channel()).getConnectionAttributes();
                String binlogFileName = connectionAttributes.getBinlogFileName().trim();
                long binlogFilePosition = connectionAttributes.getBinlogFilePosition();
                if (null != binlogFileName && binlogFileName.length() > 0)
                {
                    // 说明已经预设了起点
                    // 不需要进行FetchBinlogNamePositionResultHandler
                    channelHandlerContext.pipeline().remove(Constants.FETCH_BINLOG_NAMEPOSITION_RESULT_HANDLER);
                    // 直接跳到fetchbinlogchecksum环节
                    new FetchBinlogChecksumCommand("show global variables like 'binlog_checksum'").write(channelHandlerContext);
                    log.info("binlog positon specified :" + binlogFileName + ":" + binlogFilePosition + ", try to fetch checksum");
                } else
                {
                    new FetchBinlogNamePositionCommand("show master status").write(channelHandlerContext);
                    log.info("try to fetch binlog current name&positon");
                }
            }
            channelHandlerContext.pipeline().remove(this);// 完成使命，退出历史舞台
        } catch (Exception e)
        {
            log.info(e.toString());
            throw new Exception(e);
        }

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext channelHandlerContext, Throwable throwable)
    {
        // Close the connection when an exception is raised.
        // cause.printStackTrace();//务必要关闭
        log.info(throwable.toString());
        Nettys.cleanChannelContext(channelHandlerContext, throwable);
    }

    @Override
    public void channelInactive(ChannelHandlerContext channelHandlerContext) throws Exception
    {
        log.info("[channelInactive] socket is closed by remote server");
        Nettys.cleanChannelContext(channelHandlerContext, null);
    }

}
